package com.sunwayhorizo.health.business.integration.converter;

import java.text.*;
import java.util.*;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.validation.*;
import org.jboss.seam.*;
import org.jboss.seam.annotations.*;
import org.jboss.seam.log.*;
import com.sunwayhorizo.health.business.dto.patad.empi.*;
import com.sunwayhorizo.health.business.dto.patad.encounter.*;
import com.sunwayhorizo.health.business.dto.registries.*;
import com.sunwayhorizo.health.business.integration.model.*;
import com.sunwayhorizo.health.business.patad.empi.query.*;
import com.sunwayhorizo.health.business.patad.encounter.query.PatientEncounterQueryLocal;
import com.sunwayhorizo.health.business.registries.employee.*;
import com.sunwayhorizo.health.business.registries.organization.query.*;
import com.sunwayhorizo.health.business.registries.place.query.*;
import com.sunwayhorizo.health.common.*;
import com.sunwayhorizo.health.ets.base.service.*;
import com.sunwayhorizo.health.ets.exceptions.*;
import com.sunwayhorizo.health.hl7.common.*;
import com.sunwayhorizo.health.hl7.rim.*;
import com.sunwayhorizo.health.hl7.vocabulary.ActCode;
import com.sunwayhorizo.health.hl7.vocabulary.ActIICode;

import static com.sunwayhorizo.health.hl7.vocabulary.EntityCdSetCode.*;

@Name("Converter")
@Stateless
public class Converter implements ConverterLocal
{

    @Logger
    public Log log;

    private Validator validater = Validation.buildDefaultValidatorFactory().getValidator();
    PatientQueryLocal patientQuery = (PatientQueryLocal) Component.getInstance("PatientQuery");


    // 组装患者信息
    @Override
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public EntitysDTO convertToEntitysDTO(PatientInfo patientInfo) throws ETSBadParameterException, ETSDataException
    {
        if (patientInfo == null)
        {
            return null;
        }
        validateThrowsException(patientInfo);
        EntitysDTO entitysDTO = new EntitysDTO();
        entitysDTO.setPatientBaseInfo(convertToPatientBaseInfoDTO(patientInfo));
        entitysDTO.setListMedicalCard(convertToMedicalCardDTOs(patientInfo));
        entitysDTO.setListInsurance(convertToInfoInsuranceDTOs(patientInfo));

        return entitysDTO;
    }


    // 验证方法
    @SuppressWarnings("rawtypes")
    private void validateThrowsException(Object o)
    {
        Set<ConstraintViolation<Object>> sets = validater.validate(o);
        if (!sets.isEmpty())
        {
            StringBuilder sb = new StringBuilder();
            for (ConstraintViolation c : sets)
            {
                sb.append(c.getMessage() + "\n");
            }
            log.info(sb);
        }
    }


    // 组装PatientBaseInfoDTO
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    private PatientBaseInfoDTO convertToPatientBaseInfoDTO(PatientInfo patientInfo) throws ETSBadParameterException, ETSDataException
    {
        PatientBaseInfoDTO baseDTO = new PatientBaseInfoDTO();
        ETSService eTSService = (ETSService) Component.getInstance("ETSService");

        // 基本信息类
        baseDTO.setNatureId(patientInfo.getNature_id());
        baseDTO.setNatureName(patientInfo.getNature_name());
        baseDTO.setPinyinCode(patientInfo.getPinyin_code());
        baseDTO.setWubiCode(patientInfo.getWubi_code());
        baseDTO.setFullSpellCode(patientInfo.getFullspell_code());
        baseDTO.setNatureBirthdate(patientInfo.getNature_birthdate());
        baseDTO.setMarryFlag(patientInfo.getMarry_flag());
        baseDTO.setSocietyHomeAddress(patientInfo.getSocietyhome_address());
        baseDTO.setSocietyHomeCode(patientInfo.getSocietyhome_code());
        baseDTO.setSocietyMobile(patientInfo.getSociety_mobile());
        baseDTO.setSocietyPhone(patientInfo.getSociety_phone());
        baseDTO.setSocietyEmail(patientInfo.getSociety_email());
        baseDTO.setNativePlace(patientInfo.getNature_place());
        baseDTO.setNatureDescription(patientInfo.getNaturedesc() == null ? "" : patientInfo.getNaturedesc().toString());

        // 字典类
        if (StrUtil.isNotEmpty(patientInfo.getMarry_flag()))
        {
            baseDTO.setMerryFlagDic(eTSService.findConceptsObj(MARITALSTATUSCODE.getCodingschemeEnName(), patientInfo.getMarry_flag()));
        }
        if (StrUtil.isNotEmpty(patientInfo.getNature_sex()))
        {
            baseDTO.setNatureSexDic(eTSService.findConceptsObj(ADMINISTRATIVEGENDERCODE.getCodingschemeEnName(), patientInfo.getNature_sex()));
        }
        if (StrUtil.isNotEmpty(patientInfo.getNature_work()))
        {
            baseDTO.setSocietyWorkDic(eTSService.findConceptsObj(PROFESSIONCODE.getCodingschemeEnName(), patientInfo.getNature_work()));
        }
        if (StrUtil.isNotEmpty(patientInfo.getNature_nationality()))
        {
            baseDTO.setNatureNationalityDic(eTSService.findConceptsObj(NATIONALITYCODE.getCodingschemeEnName(), patientInfo.getNature_nationality()));
        }
        if (StrUtil.isNotEmpty(patientInfo.getNature_nation()))
        {
            baseDTO.setNatureNationDic(eTSService.findConceptsObj(ETHNICGROUPCODE.getCodingschemeEnName(), patientInfo.getNature_nation()));
        }
        if (StrUtil.isNotEmpty(patientInfo.getNature_identity()))
        {
            baseDTO.setNatureIdentityDic(eTSService.findConceptsObj(IDENTITYCODE.getCodingschemeEnName(), patientInfo.getNature_identity()));
        }
        return baseDTO;

    }


    // 组装证件dto
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    private List<MedicalCardDTO> convertToMedicalCardDTOs(PatientInfo patientInfo) throws ETSBadParameterException, ETSDataException
    {
        ETSService eTSService = (ETSService) Component.getInstance("ETSService");
        List<MedicalCardDTO> medicalCardDTOs = new ArrayList<MedicalCardDTO>();
        for (String medicalCord : patientInfo.getMedical_cord().split(","))
        {
            log.info(medicalCord);
            if (medicalCord.startsWith("\\") || medicalCord.startsWith("/") || medicalCord.startsWith("\\|") || medicalCord.startsWith("-")
                    || medicalCord.split("\\|").length < 2 || medicalCord.split("\\|")[1].equals("\\") || medicalCord.split("\\|")[1].equals("/")
                    || medicalCord.split("\\|")[1].equals("-") || medicalCord.split("\\|")[1].equals("未带"))
            {
                continue;
            }
            MedicalCardDTO medicalCardDTO = new MedicalCardDTO();
            medicalCardDTO.setTypeDic(eTSService.findConceptsObj("DocumentType", medicalCord.split("\\|")[0].length() == 2 ? medicalCord.split("\\|")[0]
                    : "0" + medicalCord.split("\\|")[0]));
            medicalCardDTO.setId(medicalCord.split("\\|").length == 2 ? medicalCord.split("\\|")[1] : "");

            medicalCardDTOs.add(medicalCardDTO);
        }

        return medicalCardDTOs;
    }


    // 组装医保dto
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    private List<InfoInsuranceDTO> convertToInfoInsuranceDTOs(PatientInfo patientInfo) throws ETSBadParameterException, ETSDataException
    {
        ETSService eTSService = (ETSService) Component.getInstance("ETSService");
        List<InfoInsuranceDTO> infoInsuranceDTOs = new ArrayList<InfoInsuranceDTO>();
        for (String insuranceCord : patientInfo.getInsurance_cord().split(","))
        {
            if (insuranceCord.startsWith("\\") || insuranceCord.startsWith("/") || insuranceCord.startsWith("\\|") || insuranceCord.startsWith("-"))
            {
                continue;
            }

            InfoInsuranceDTO infoInsuranceDTO = new InfoInsuranceDTO();
            infoInsuranceDTO.setId(insuranceCord.split("\\|")[0]);
            infoInsuranceDTO.setTypeDic(eTSService.findConceptsObj("MedicareType", insuranceCord.split("\\|")[1]));
            infoInsuranceDTO.setUnit(insuranceCord.split("\\|")[2]);
            infoInsuranceDTO.setState(insuranceCord.split("\\|")[3].equals("1") ? "在用" : "未用");
            infoInsuranceDTOs.add(infoInsuranceDTO);
        }
        return infoInsuranceDTOs;
    }


    // 组装入院dto
    @Override
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public PatientEncounterDTO convertToPatientEncounterDTO(InHospitalInfo inHospitalInfo) throws ETSBadParameterException, ETSDataException,
        Hl7Exception
    {
        ETSService eTSService = (ETSService) Component.getInstance("ETSService");

        PatientEncounterDTO dto = new PatientEncounterDTO();
        dto.setHospitalizationNO(inHospitalInfo.getHospitalzation_no());
        dto.setInHospitalDTO(convertToInHospitalDTO(inHospitalInfo));
        dto.setEncounterType(ActCode.HOSPITALIZED.code().stringValue());
        if (StrUtil.isNotEmpty(inHospitalInfo.getChatgetype()))
        {
            dto.setChargeTypeDic(eTSService.findConceptsObj("ChargeType",inHospitalInfo.getChatgetype()));
        }
        dto.getPatientBaseInfoDTO().setNatureId(inHospitalInfo.getNature_id());
        if (StrUtil.isNotEmpty(inHospitalInfo.getOperator_by()) && inHospitalInfo.getOperator_by().split("\\|").length > 0)
        {
            dto.getLoginBaseInfo().setOperateId(inHospitalInfo.getOperator_by().split("\\|")[0]);

            @SuppressWarnings("unused")
            EmployeeManagerLocal emManager = (EmployeeManagerLocal) Component.getInstance("EmployeeManager");

            dto.getLoginBaseInfo().setOperateName(
                inHospitalInfo.getOperator_by().split("\\|").length == 2 ? inHospitalInfo.getOperator_by().split("\\|")[1] : "");
        }
        return dto;
    }


    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    private InHospitalDTO convertToInHospitalDTO(InHospitalInfo info) throws ETSBadParameterException, ETSDataException, Hl7Exception
    {
        InHospitalDTO dto = new InHospitalDTO();
        dto.setAdmissionPurpose(info.getAdmission_purpose() == null ? "Treatment" : info.getAdmission_purpose());
        dto.setAdmissionTime(new SimpleDateFormat("yyyyMMddHHmmss").format(info.getAdmission_time()));
        dto.setAdmissionWay(info.getAdmission_way() == null ? "OutPatService" : info.getAdmission_way());
        String deptId = info.getDept().split("\\|")[0];

        DepartmentQueryLocal departmentManager = (DepartmentQueryLocal) Component.getInstance("DepartmentQuery");
        com.sunwayhorizo.health.hl7.rim.Role role = departmentManager.findWorkGroupRoleByWorkGroupCode(deptId);
        String roleId = "0";
        if (role != null)
        {
            roleId = role.getRoleId().toString();
        }

        dto.setRoleID(roleId);
        dto.setDeptName(info.getDept().split("\\|")[1]);
        dto.setHospitalizationNO(info.getHospitalzation_no());

        dto.setEncounterNum(info.getEncounter_num());
        dto.setLinkMan(info.getLink_man());
        dto.setLinkManWay(info.getLinkman_way());
        if (info.getOut_doctor() != null && !info.getOut_doctor().equals("") && info.getOut_doctor().split("\\|").length > 0)
        {
            dto.setDoctorId(info.getOut_doctor().split("\\|")[0]);
            dto.setDoctorName(info.getOut_doctor().split("\\|").length == 2 ? info.getOut_doctor().split("\\|")[1] : "");
        }
        ETSService eTSService = (ETSService) Component.getInstance("ETSService");

        // 字典类
        if (info.getOutpat_diagnose().split("\\|").length > 0 && "".equals(info.getOutpat_diagnose().split("\\|")[0]))
        {

            dto.setOutPatDiagnose(eTSService.findConceptsDTOByCodeAndEnName("Diagnosis", info.getOutpat_diagnose().split("\\|")[1]));
        }
        else if (info.getOutpat_diagnose().split("\\|").length > 1)
        {
            dto.setOutPatDiagnose(eTSService.findConceptsDTO(info.getOutpat_diagnose().split("\\|")[0], info.getOutpat_diagnose().split("\\|")[1]));
        }
        return dto;
    }


    // 入出转
    @Override
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public PatientEncounterDTO convertToPatientEncounterDTO(PatientStatusInfo info) throws ETSBadParameterException, ETSDataException, Hl7Exception
    {

        if (info.getAction().equals("1"))
        {
            return convertInDepartmentInfo(info);
        }
        else if (info.getAction().equals("2"))
        {
            return convertChangeDepartmentInfo(info);
        }
        else if (info.getAction().equals("3"))
        {
            return convertOutHospitalInfo(info);
        }
        else
        {
            return null;
        }
    }


    private void setEncounterId(PatientStatusInfo info, PatientEncounterDTO dto) throws Hl7Exception
    {
        PatientEncounterQueryLocal patientEncounterQuery = (PatientEncounterQueryLocal) Component.getInstance("PatientEncounterQuery");
        PatientEncounter inhos = patientEncounterQuery.findLastInhosActByPatientNatureId(info.getNature_id());
        if (inhos != null)
        {
            dto.setEncounterID(inhos.getId(ActIICode.HOSPITALIZED).clinicNo().stringValue());
        }
    }


    // 出院
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    private PatientEncounterDTO convertOutHospitalInfo(PatientStatusInfo info) throws Hl7Exception
    {
        PatientEncounterDTO dto = new PatientEncounterDTO();
        setEncounterId(info, dto);
        dto.getDischargedDTO().setBedNo(info.getBed_no());
        dto.getDischargedDTO().setOutTime(new SimpleDateFormat("yyyyMMddHHmmss").format(info.getAction_time()));
        dto.getDischargedDTO().setPatientNeturalId(info.getNature_id());
        dto.getLoginBaseInfo().setOperateId(info.getOperator_by().split("\\|")[0]);
        String deptId = info.getDept().split("\\|")[0];
        dto.getPatientBaseInfoDTO().setNatureId(info.getNature_id());

        DepartmentQueryLocal departmentManager = (DepartmentQueryLocal) Component.getInstance("DepartmentQuery");
        com.sunwayhorizo.health.hl7.rim.Role workgroupRole = departmentManager.findWorkGroupRoleByWorkGroupCode(deptId);
        String workgrouproleId = "0";
        if (workgroupRole != null)
        {
            workgrouproleId = workgroupRole.getRoleId().toString();
        }

        BedQueryLocal bedDao = (BedQueryLocal) Component.getInstance("BedQuery");
        com.sunwayhorizo.health.hl7.rim.Role bedRole = bedDao.findBedRoleByBedNoAndWorkGroupRoleId(info.getBed_no(), workgrouproleId);
        dto.getDischargedDTO().setWorkgroupCode(deptId);
        dto.getDischargedDTO().setBedRoleId(bedRole == null ? "" : bedRole.getRoleId().toString());
        dto.getInDepartment().setWorkGroupId(workgrouproleId);
        return dto;
    }


    // 转科
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    private PatientEncounterDTO convertChangeDepartmentInfo(PatientStatusInfo info) throws Hl7Exception
    {
        PatientEncounterDTO dto = new PatientEncounterDTO();
        setEncounterId(info, dto);
        dto.getPatientBaseInfoDTO().setNatureId(info.getNature_id());
        dto.getTransferDTO().setAdmissionTime(new SimpleDateFormat("yyyyMMddHHmmss").format(info.getAction_time()));
        dto.getLoginBaseInfo().setOperateId(info.getOperator_by().split("\\|")[0]);

        String deptCode = info.getDept().split("\\|")[0];
        dto.getTransferDTO().setToWorkgroupCode(deptCode);
        dto.getTransferDTO().setFromWorkgroupCode(info.getFrom_dept().split("\\|")[0]);

        dto.getTransferDTO().setBedNo(info.getBed_no());
        return dto;
    }


    // 入科
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    private PatientEncounterDTO convertInDepartmentInfo(PatientStatusInfo info) throws Hl7Exception
    {
        PatientEncounterDTO dto = new PatientEncounterDTO();
        setEncounterId(info, dto);
        dto.getPatientBaseInfoDTO().setNatureId(info.getNature_id());
        Patient patient = patientQuery.findPatientByNeturalId(info.getNature_id());
        if (patient != null)
        {
            log.info("Converter-convertInDepartmentInfo-patientRoleId" + patient.getRoleId().toString());
            dto.getPatientBaseInfoDTO().setPersonId(patient.getRoleId().toString());
        }
        else
        {
            log.info("Converter-convertInDepartmentInfo-患者id不存在!");

            // throw new ValidationException("患者id不存在！");
        }
        dto.getInDepartment().setBedNO(info.getBed_no());
        DepartmentQueryLocal departmentManager = (DepartmentQueryLocal) Component.getInstance("DepartmentQuery");
        com.sunwayhorizo.health.hl7.rim.Role role = departmentManager.findWorkGroupRoleByWorkGroupCode(info.getDept().split("\\|")[0]);
        if (role != null)
        {
            dto.getInDepartment().setWorkGroupId(role.getRoleId().toString());
        }
        dto.getLoginBaseInfo().setOperateId(info.getOperator_by().split("\\|")[0]);
        dto.getPatientBaseInfoDTO().setNatureId(info.getNature_id());
        dto.getInDepartment().setAdmissionTime(new SimpleDateFormat("yyyyMMddHHmmss").format(info.getAction_time()));
        dto.getInHospitalDTO().setEncounterNum(info.getEncounter_num());
        return dto;
    }


    @Override
    public PatientEncounterDTO setReceivingDoctor(PatientStatusInfo info, PatientEncounterDTO dto)
    {
        if (info.getDoctor() != null)
        {
            dto.getLoginBaseInfo().setOperateId(info.getDoctor().split("\\|")[0]);
        }
        return dto;
    }


    public Log getLog()
    {
        return log;
    }


    public void setLog(Log log)
    {
        this.log = log;
    }

}
